package com.sinaapp.msdxblog.tools.htmlsax;

/*
 * @(#)TVHtmlParser.java		       Project:Tools
 * Date:2012-8-14
 *
 * Copyright (c) 2011 CFuture09, Institute of Software, 
 * Guangdong Ocean University, Zhanjiang, GuangDong, China.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.sinaapp.msdxblog.tools.htmlsax.vo.Area;
import com.sinaapp.msdxblog.tools.htmlsax.vo.Channel;
import com.sinaapp.msdxblog.tools.htmlsax.vo.Program;
import com.sinaapp.msdxblog.tools.htmlsax.vo.Station;

/**
 * @author Geek_Soledad (66704238@51uc.com)
 */
public class TVHtmlParser {
	protected static final String CHANNEL_URL = "http://www.tvmao.com/program/channels/";
	protected static final String PROGRAM_TV_URL = "http://www.tvmao.com/program";
	protected static final String BASE_URL = "http://www.tvmao.com";

	/**
	 * 从网页的源码中分离出地区的内容。
	 * 
	 * @return 包含地区的网页源码
	 */
	protected static Element splitArea() {
		Element element = null;
		try {
			Document document = Jsoup.parse(new URL(CHANNEL_URL), 3000);
			Elements elements = document.getElementsByTag("table");
			if (elements != null && elements.size() > 0) {
				element = elements.get(0);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return element;
	}

	/**
	 * 从网页的源码中分离出频道的内容。
	 * 
	 * @param htmlResource
	 *            网页源码
	 * @return 包含频道的网页源码。
	 */
	protected static Element splitChannel(String url) {
		return getElementByClassName(url, "chlsnav");
	}

	/**
	 * 从网页源码中分离出节目的内容。
	 * 
	 * @param htmlResource
	 *            网页源码
	 * @return 包含节目的网页源码。
	 */
	protected static Element splitProgram(String url) {
		return getElementByClassName(url, "pgmain");
	}

	/**
	 * 从网页源码中根据className获取元素。
	 * 
	 * @param url
	 *            网页url。
	 * @param className
	 *            选择器
	 * @return 获取到的元素。
	 */
	private static Element getElementByClassName(String url, String className) {
		Element element = null;
		try {
			Document document = Jsoup.parse(new URL(url), 3000);
			Elements elements = document.getElementsByClass(className);
			if (elements != null && elements.size() > 0) {
				element = elements.get(0);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return element;
	}

	/**
	 * 获取支持的所有地区。
	 * 
	 * @return 所有地区，List对象。
	 */
	public static List<Area> getAreas() {
		Element areaElement = splitArea();
		List<Area> areas = new ArrayList<Area>();
		Elements elements = areaElement.select("a[title]");
		for (Element element : elements) {
			if(element.text().contains("卫视")) {
				continue;
			}
			Area area = new Area(element.text(), element.attr("href"));
			areas.add(area);
		}
		return areas;
	}

	/**
	 * 获取所支持的电视台。
	 * 
	 * @param extUrl
	 *            地区的相对URL。
	 * @return
	 */
	public static List<Station> getStations(String extUrl) {
		List<Station> stations = new ArrayList<Station>();
		Element stationElement = splitChannel(BASE_URL + extUrl);
		Element element1 = stationElement.getElementsByAttributeValue("class",
				"pbar").get(0);
		Station station = new Station(element1.text(), extUrl);
		station.setShowing(true);
		stations.add(station);
		Elements elements = stationElement.select("a[href]");
		for (Element element : elements) {
			if (!element.getElementsByClass("plst").isEmpty()) {
				Station station2 = new Station(element.text(),
						element.attr("href"));
				stations.add(station2);
			}
		}
		return stations;
	}

	/**
	 * 获取支持的该电视台的频道列表。
	 * 
	 * @param extUrl
	 *            电视台的相对URL。
	 * @return 频道列表。
	 */
	public static List<Channel> getChannels(String extUrl) {
		Element element = splitChannel(BASE_URL + extUrl);
		if (element == null) {
			return null;
		}
		Element channelElement = element.select("ul").first();
		Elements elements = channelElement.select("li");

		return getChannelList(extUrl, elements);
	}
	/**
	 * 获取频道列表。由getChannel方法调用。
	 * 
	 * @param extUrl
	 *            展开的电视台的URL。
	 * @param elements
	 * @return 频道列表。
	 */
	private static List<Channel> getChannelList(String extUrl, Elements elements) {
		List<Channel> channels = new ArrayList<Channel>();
		Channel channel;
		for (Element element : elements) {
			Element e = element.select("a[href]").first();
			if (e == null) {
				channel = new Channel(element.text(), extUrl);
				channel.setShowing(true);
			} else {
				channel = new Channel(e.text(), e.attr("href"));
			}
			channels.add(channel);
		}
		return channels;
	}
	/**
	 * 获取某频道的节目表。
	 * 
	 * @param extUrl
	 *            频道及时间所对应的相对URL。
	 * @return 节目列表。
	 */
	public static List<Program> getPrograms(String extUrl) {
		List<Program> programs = new ArrayList<Program>();
		Element programElement = splitProgram(BASE_URL + extUrl);
		Elements elements = programElement.select("li");
		for (Element element : elements) {
			Program program = new Program();
			// 获取时间
			Element e = element.select("span").first();
			if (e == null) {
				continue;
			}
			program.setTime(e.text());
			e.remove();

			// 获取剧情。
			program.setDrama(getProgramDrama(element));

			// 节目名称。
			program.setName(getProgramName(element));
			programs.add(program);
		}

		return programs;
	}

	/**
	 * 获取节目剧情
	 * 
	 * @param element
	 *            节目的节点。
	 * @return 节目剧情。
	 */
	private static String getProgramDrama(Element element) {
		StringBuilder drama = new StringBuilder();
		Element e2 = element.select("div.tvgd").first();
		if (e2 != null) {
			e2.select("a.drama").remove();
			Elements es2 = e2.select("p");
			for (Element element2 : es2) {
				drama.append(element2.text()).append("\n");
			}
			e2.remove();
		} else {
			e2 = element.select("div.tvcgd").first();
			if (e2 != null) {
				drama.append(e2.ownText());
				e2.remove();
			}
		}
		return drama.toString();
	}

	/**
	 * 获取节目名称。
	 * 
	 * @param element
	 *            节目的节点。
	 * @return 节目名称。
	 */
	private static String getProgramName(Element element) {
		Elements es = element.select("a[href]");
		if (!es.isEmpty()) {
			for (Element element2 : es) {
				if (element2.hasAttr("class")) {
					element2.remove();
				}
			}
		}
		return element.text();
	}
}
